/*********************************************************************************
 * File Name: ScenarioDBImpl.java
 * Package Name: com.sensorfriendly.provider.impl
 * 
 * Purpose:
 * A class the defines all the operations to be performed
 * on the Message Table
 *  
 *********************************************************************************/

package com.sensorfriendly.provider.impl;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;

import com.sensorfriendly.AppConstants;
import com.sensorfriendly.model.Message;
import com.sensorfriendly.model.Scenario;

public class ScenarioDBImpl {
	private Context mContext;
	private static MessageDBImpl messageDB; 
	
	// Constructor
	public ScenarioDBImpl(Context context){
		mContext=context;
		messageDB = new MessageDBImpl(mContext);
	}
	
	// Insert a new Scenario into the DB if it
	// does not already exist
	public boolean insertScenario(Scenario scenario){
		if(!exists(scenario)){
			ContentResolver resolver = mContext.getContentResolver();
			ContentValues value = getQueryValues(scenario);
			resolver.insert(ScanarioTable.CONTENT_URI, value);
			if(!(scenario.getMessages()==null)){
				for(Message message : scenario.getMessages()){
					messageDB.insertMessage(message);
				}
			}
			return false;
		}
		return true;
	}
	
	// Gets all the scenarios
	public List<Scenario> getAllScenarios(){
		List<Scenario> items = new ArrayList<Scenario>();
		ContentResolver resolver = mContext.getContentResolver();
		Cursor cursor =resolver.query(ScanarioTable.CONTENT_URI, null, null, null, null);
		while (cursor != null && cursor.getCount() > 0 && !cursor.isLast()){
			Scenario item =  fillFromCursor(cursor);
			items.add(item);
		}
		safelyCloseCursor(cursor);
		for(Scenario s : items){
			List<Message> messages = messageDB.getMessagesForScenario(s.getName());
			s.setMessages(messages);
		}
		return items;
	}
	
	// Gets the given scenario name
	public Scenario getScenario(String scenarioName){
		ContentResolver resolver = mContext.getContentResolver();
		String where = ScanarioTable.SCENARIO_NAME + "="+DatabaseUtils.sqlEscapeString(scenarioName);
		Cursor cursor =resolver.query(ScanarioTable.CONTENT_URI, null, where, null, null);
		Scenario item = null;
		if (cursor != null && cursor.getCount() > 0 && !cursor.isLast()){
			item =  fillFromCursor(cursor);
		}
		safelyCloseCursor(cursor);
		if(item == null){
			return item;
		}
		List<Message> messages = messageDB.getMessagesForScenario(item.getName());
		item.setMessages(messages);
		return item;
	}
	
	// Gets the list of scenarios for the given pageIndex
	public List<Scenario> getScenariosForPage(int pageNum) {
		List<Scenario> items = new ArrayList<Scenario>();
		ContentResolver resolver = mContext.getContentResolver();
		Cursor cursor =resolver.query(ScanarioTable.CONTENT_URI, null, null, null, null);
		cursor.move(pageNum*AppConstants.ITEM_PER_PAGE);
		int count =0;
		while (cursor != null && cursor.getCount() > 0 && !cursor.isLast() && count < AppConstants.ITEM_PER_PAGE){
			Scenario item =  fillFromCursor(cursor);
			items.add(item);
			count++;
		}
		safelyCloseCursor(cursor);
		for(Scenario s : items){
			List<Message> messages = messageDB.getMessagesForScenario(s.getName());
			s.setMessages(messages);
		}
		return items;
	}
	
	// Update the Old Scenario with the New Scenario Name
	public void updateScenario(String oldName, Scenario scenario){
		String where = ScanarioTable.SCENARIO_NAME + "="+ DatabaseUtils.sqlEscapeString(oldName);
		ContentValues fields = getQueryValues(scenario);
		ContentResolver resolver = mContext.getContentResolver();
		int udpated = resolver.update(ScanarioTable.CONTENT_URI, fields, where, null);
		for(Message msg : scenario.getMessages()){
			msg.setScenarioName(scenario.getName());
			messageDB.updateMessage(msg.getMessageContent(), msg);
		}
	}
	
	// Delete the given Scenario and all the messages under it
	public int deleteScenario(String scenarioName){
		ContentResolver resolver = mContext.getContentResolver();
		String where = ScanarioTable.SCENARIO_NAME + "="+DatabaseUtils.sqlEscapeString(scenarioName);
		messageDB.deleteMessageForScenario(scenarioName);
		return resolver.delete(ScanarioTable.CONTENT_URI, where, null);
	}
	
	// Returns the total Scenario's cursor count
	public int getScenarioCount(){
		ContentResolver resolver = mContext.getContentResolver();
		Cursor cursor =resolver.query(ScanarioTable.CONTENT_URI, null, null, null, null);
		return cursor.getCount();
	}
	
	// Fill up the cursor with the next set Scenarios 
	// from the DB
	public Scenario fillFromCursor(Cursor cursor){
		cursor.moveToNext();
		Scenario scenario = new Scenario();
		scenario.setName(cursor.getString(cursor.getColumnIndex(ScanarioTable.SCENARIO_NAME)));
		scenario.setTimeCreated(cursor.getLong(cursor.getColumnIndex(ScanarioTable.TIME_POSTED)));
		scenario.setIconPath(cursor.getString(cursor.getColumnIndex(ScanarioTable.ICON_FILE_NAME)));
		return scenario;
	}
	
	// Returns the values of the input Scenario Name
	private ContentValues getQueryValues(Scenario scenrio){
		ContentValues value = new ContentValues();
		Long time;
		if((time=scenrio.getTimeCreated()) == null){
			time = System.currentTimeMillis();
		}
		value.put(ScanarioTable.TIME_POSTED, time);
		value.put(ScanarioTable.SCENARIO_NAME,  scenrio.getName());
		value.put(ScanarioTable.ICON_FILE_NAME, scenrio.getIconPath());
		return value;
	}
	
	// Checks if the given Scenario Name exists in the
	// DB or not
	private boolean exists(Scenario scenario){
		ContentResolver resolver = mContext.getContentResolver();
		String where = ScanarioTable.SCENARIO_NAME + "="+DatabaseUtils.sqlEscapeString(scenario.getName());
		Cursor cursor =resolver.query(ScanarioTable.CONTENT_URI, null, where, null, null);
		if(cursor == null){
			return false;
		}
		boolean exists = !(cursor.getCount()==0);
		safelyCloseCursor(cursor);
		return exists;
	}
	
	// Safely close the cursor
	private void safelyCloseCursor(Cursor cur) {
		if(cur != null && cur.isClosed() == false)
			cur.close();
	}
}
